/*
* @(#)ListCalendarAction.java
*
* Copyright (c) 2003 DCIVision Ltd
* All rights reserved.
*
* This software is the confidential and proprietary information of DCIVision
* Ltd ("Confidential Information").  You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with DCIVision Ltd.
*/

package com.dcivision.calendar.web;

import java.sql.Connection;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.dcivision.alert.bean.UpdateAlert;
import com.dcivision.alert.bean.UpdateAlertSystemLog;
import com.dcivision.alert.bean.UpdateAlertType;
import com.dcivision.alert.core.AlertManager;
import com.dcivision.alert.dao.UpdateAlertDAObject;
import com.dcivision.alert.dao.UpdateAlertSystemLogDAObject;
import com.dcivision.alert.dao.UpdateAlertTypeDAObject;
import com.dcivision.calendar.CalendarUtility;
import com.dcivision.calendar.bean.CalendarPerference;
import com.dcivision.calendar.bean.CalendarRecord;
import com.dcivision.calendar.core.CalendarRetrievalManager;
import com.dcivision.calendar.dao.CalendarPerferenceDAObject;
import com.dcivision.calendar.dao.CalendarRecordDAObject;
import com.dcivision.calendar.dao.CalendarRecurDAObject;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.framework.web.AbstractListAction;
import com.dcivision.framework.web.AbstractSearchForm;
import com.dcivision.user.dao.UserGroupDAObject;


/**
 * <p>Class Name:       ListCalendarAction.java    </p>
 * <p>Description:      The list action class for ListCalendar.jsp</p>
 *
 *    @author           Jenny Li
 *    @company          DCIVision Limited
 *    @creation date    05/12/2003
 *    @version          $Revision: 1.40 $
 */


public class ListCalendarRecordAction extends AbstractListAction {

  public static final String REVISION = "$Revision: 1.40 $";


  Logger logger = Logger.getLogger("com.dcivision.calendar");
  String toDoListName = "";
  String userListName = "";
  String groupListName = "";
  //ListCalendarRecordBean intance=ListCalendarRecordBean.getInstance();
  CalendarRetrievalManager intance = null;



  /** Creates a new instance of LoginAction */
  public ListCalendarRecordAction() {
    super();
    this.setListName("calendarRecord");
    this.toDoListName = this.getListName() + "_toDoList";
    this.userListName = this.getListName() + "_userList";
    this.groupListName = "allGroupList";
  }

  /**
   * getMajorDAOClassName
   *
   * @return  The class name of the major DAObject will be used in this action.
   */
  public String getMajorDAOClassName() {
    return ("com.dcivision.calendar.dao.CalendarRecordDAObject");
  }

  /**
   * getFunctionCode
   *
   * @return  The corresponding system function code of action.
   */
  public String getFunctionCode() {
    return (SystemFunctionConstant.SCHEDULE_CALENDAR);
  }


  /**
   *  Method execute() - generaic function of result list handling, including:
   *                     1. Delete record in List
   *                     2. Get List Data
   * @param mapping                   ActionMapping from struts
   * @param form                      ActionForm from struts
   * @param request                   HttpServletReuqest
   * @param response                  HttpServletRespond
   * @return  ActionForward           Return the action forward object for struts
   * @throws ServletException         Throws ServletException
   */
  public ActionForward execute(ActionMapping mapping,
                               ActionForm form,
                               HttpServletRequest request,
                               HttpServletResponse response)
      throws ServletException {

  	/*
  	 * Update Code Start
  	 * Author				Jim.Zhou
  	 * Date					2006/05/23
  	 * Bug					#5088
  	 */
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    CalendarPerference calendarPerference = null;
    
    intance = new CalendarRetrievalManager(sessionContainer,conn);
    /*
     * Update Code End
     */
		/*
		 *	Update Code Start
		 *	Author					Jim.Zhou
		 *	Date						2006/06/07
		 *	Bug							#5639
		 */
  	if (!Utility.isEmpty(request.getParameter("isNew"))){
  		if ("true".equals(request.getParameter("isNew"))){
  			request.getSession().setAttribute("CALENDAR_SELECTED_DATE",null);
  			//Code Add By Jim.Zhou			2006/06/07			Bug #5637
  			request.getSession().setAttribute("CALENDAR_SELECTED_GROUPID",null);
  			request.getSession().setAttribute("CALENDAR_SELECTED_USERID",null);
  			//Code Add End
  		}
  	}
		/*
		 *	Update Code End
		 */

    if (form != null && GlobalConstant.OP_MODE_LIST_RETAIN.equals(((AbstractSearchForm)form).getOpMode())) {
     // Retain the attributes of search form.
    /*
     * Update Code Start
     * Author			Jim.Zhou
     * Date				2006/05/22
     * Bug				#5100
     */
     //String m_sListName=request.getParameter("listName");
     if ((ActionForm)request.getSession().getAttribute(this.m_sListName)!=null) {
       form = (ActionForm)request.getSession().getAttribute(this.m_sListName);
       request.setAttribute(mapping.getAttribute(), form);
     } else {
       request.getSession().setAttribute(this.m_sListName, form);
     }
    } else {
	  	 /*
	  	  * Update Code Start
	  	  * Author				Jim.Zhou
	  	  * Date					2006/05/23
	  	  * Bug						#5088
	  	  */
       // Set the search from into session for remembering the settings.
    	 if (Utility.isEmpty(((AbstractSearchForm)form).getOpMode())&&Utility.isEmpty(((AbstractSearchForm)form).getNavMode())){
    		 CalendarPerferenceDAObject calendarPerferenceDAO = new CalendarPerferenceDAObject(sessionContainer,conn);
    		 if (!Utility.isEmpty(calendarPerferenceDAO.getByObjectByUserRecordID(sessionContainer.getUserRecordID()))){
      		 calendarPerference = (CalendarPerference)calendarPerferenceDAO.getByObjectByUserRecordID(sessionContainer.getUserRecordID());
      		 //((MaintCalendarPerferenceForm)form).setFormData(calendarPerference);
      		 if (!Utility.isEmpty(calendarPerference.getDefaultGroup())){
        		 ((AbstractSearchForm)form).setBasicSearchField(calendarPerference.getDefaultGroup().toString());
        		 ((AbstractSearchForm)form).setBasicSearchType("-1");
      		 }
    		 }
    		 request.getSession().setAttribute(this.m_sListName,form);
    	 } else {
    		 //Code Add By Jim.Zhou				2006/06/08			Bug #5663
    		 if (!Utility.isEmpty(request.getParameter("navMode"))){
    			 if (!"LS".equals(request.getParameter("navMode"))){
    	       request.getSession().setAttribute(this.m_sListName, form);
    			 }
    		 } else {
           request.getSession().setAttribute(this.m_sListName, form);
    		 }
    		 //Code Add End
     	 }
       //request.getSession().setAttribute(this.m_sListName, form);
    	 /*
    	  * Update Code End
    	  */
     }
     /*
      * Update Code End
      */
   //} else {
     // Set the search from into session for remembering the settings.
     //request.getSession().setAttribute(this.m_sListName, form);
   //}

    // Set the function code for current action.
    ActionForward forward = this.retrieveFunctionCode(request, response, mapping);
    if (forward!=null) {
      return forward;
    }

    String navMode = null;
    HttpSession session = request.getSession();
    AbstractSearchForm searchForm = (AbstractSearchForm) form;
    Calendar selectedDate = Calendar.getInstance();
    //getNavMode
    navMode = intance.getNavMode(this.getSessionContainer(request),
                                 this.getConnection(request), request);
    request.setAttribute("navMode",navMode);

    //Because the navMode is Daily/Weekly/Monthly,the page offset should not be limited,
    //So set the pageOffset as 10000.
    if (CalendarRecord.NAV_MODE_LIST_BY_DAY.equals(navMode) ||
        CalendarRecord.NAV_MODE_LIST_BY_WEEK.equals(navMode) ||
        CalendarRecord.NAV_MODE_LIST_BY_MONTH.equals(navMode) ) {
      searchForm.setPageOffset("10000");
    }



    // getselectedDate
    selectedDate = intance.getSelectDate(request);

    //Delete record in List
    if (GlobalConstant.OP_MODE_LIST_DELETE.equals( request.
                                                  getParameter("opMode"))) {
      this.deleteListData(mapping, searchForm, request, response);
      if (request.getSession().getAttribute(this.getListName()) != null) {
        request.getSession().removeAttribute(this.getListName());
      }
      addMessage(request, MESSAGE_RECORDS_DELETED,""+searchForm.getBasicSelectedID().length);
      searchForm.setBasicSelectedID(null);
      searchForm.setOpMode(null);
    }
    if ("SS".equals(request.getParameter("opMode"))) {
      getRecipeintListData(mapping, searchForm, request, response);
    } else {
      //getListData
      this.getListData(mapping, searchForm, request, response);
    }
    ActionForward actForward = null;
    if(!Utility.isEmpty(request.getParameter("isMessage")))
    {
      actForward = mapping.findForward(CalendarRecord.MEETING_LIST_CALENDAR_BY_WEEK);
    }else if (navMode.equals(CalendarRecord.NAV_MODE_LIST_BY_DAY)) {
      actForward = mapping.findForward(CalendarRecord.NAV_MODE_LIST_BY_DAY);
    } else if (navMode.equals(CalendarRecord.NAV_MODE_LIST_BY_WEEK)) {
      actForward = mapping.findForward(CalendarRecord.NAV_MODE_LIST_BY_WEEK);
    } else if (navMode.equals(CalendarRecord.NAV_MODE_LIST_BY_MONTH)) {
      actForward = mapping.findForward(CalendarRecord.NAV_MODE_LIST_BY_MONTH);
    } else if (navMode.equals(CalendarRecord.NAV_MODE_LIST_TODO)) {
      List resultList = (List)request.getAttribute(this.toDoListName);
      while ( (resultList.size()==0) && (TextUtility.parseInteger(searchForm.getCurStartRowNo())>TextUtility.parseInteger(searchForm.getPageOffset())) ) {
        int prvRowNo = TextUtility.parseInteger(searchForm.getCurStartRowNo())-TextUtility.parseInteger(searchForm.getPageOffset());
        searchForm.setCurStartRowNo(TextUtility.formatInteger(prvRowNo));
        this.getListData(mapping, searchForm, request, response);
        resultList = (List)request.getAttribute(this.toDoListName);
      }
      actForward = mapping.findForward(CalendarRecord.NAV_MODE_LIST_TODO);
    } else if (navMode.equals(CalendarRecord.NAV_MODE_LIST_EVENT)) {
      List resultList = (List)request.getAttribute("newEventList");
      while ( (resultList.size()==0) && (TextUtility.parseInteger(searchForm.getCurStartRowNo())>TextUtility.parseInteger(searchForm.getPageOffset())) ) {
        int prvRowNo = TextUtility.parseInteger(searchForm.getCurStartRowNo())-TextUtility.parseInteger(searchForm.getPageOffset());
        searchForm.setCurStartRowNo(TextUtility.formatInteger(prvRowNo));
        this.getListData(mapping, searchForm, request, response);
        resultList = (List)request.getAttribute("newEventList");
      }
      actForward = mapping.findForward(CalendarRecord.NAV_MODE_LIST_EVENT);
    } else if(navMode.equals("LS")){
      actForward = mapping.findForward("LS");
    } else {
      actForward = mapping.findForward(CalendarRecord.NAV_MODE_LIST_BY_WEEK);
    }

    return actForward;

  }

  /**
   * Method getListData() - retrieve the appropriate item list for current page
   * @param mapping                   ActionMapping from struts
   * @param form                      ActionForm from struts
   * @param request                   HttpServletReuqest
   * @param response                  HttpServletRespond
   * @throws ApplicationException     Throws Exception if cannot get the list data from DAO object
   */
  public void getListData(ActionMapping mapping, AbstractSearchForm form,
                          HttpServletRequest request,
                          HttpServletResponse response)
      throws ApplicationException {
    Connection conn = null;
    HttpSession session = request.getSession();

    String navMode = null;
    String appendedQuery = null;
    Integer staffID = new Integer( -1);
    int selectedUserID = -1;
    int selectedGroupID = -1;

    ArrayList userList = new ArrayList();
    ArrayList newSortList = new ArrayList();
    ArrayList newToDoList = new ArrayList();
    ArrayList eventList = new ArrayList();
    ArrayList sortedList = new ArrayList();
    ArrayList newEventList=new ArrayList();

    //getListNavMode
    navMode = intance.getListNavMode(request);
    try {
      conn = getConnection(request);
      Timestamp startDate = null;
      Timestamp endDate = null;
      ArrayList dateList = intance.getListStartEndDate(request, navMode);
      //getStartDate
      startDate = (Timestamp) dateList.get(0);
      //getEndDate
      endDate = (Timestamp) dateList.get(1);

      //getSelectedUserID
      selectedUserID = intance.getSelectedUserID(this.getSessionContainer(
          request), request);
      /*
       * Update Code Start
       * Author				Jim.Zhou
       * Date					2006/05/23
       * Bug					#5088
       */
      //getSelectedGroupID
      if (!Utility.isEmpty(form.getBasicSearchField())){
        //selectedGroupID = Integer.parseInt(form.getBasicSearchField().toString());
        selectedGroupID = intance.getSelectedGroupID(request);
      } else {
        selectedGroupID = intance.getSelectedGroupID(request);
      }
      /*
       * Update Code End
       */
      CalendarUtility util = new CalendarUtility();
      //staffID = util.getStaffRecordIDByUserID(this.getSessionContainer(request),
        //                                      this.getConnection(request));

      userList=intance.getUserList(this.getSessionContainer(request),
                          this.getConnection(request), request, selectedGroupID);
      List tempList = Utility.getList(Utility.getPropertyArray(userList, "ID", new Integer[0]));
      if ( (!tempList.contains(new Integer(selectedUserID))) &&
          (selectedUserID != -1))
        selectedUserID = this.getSessionContainer(request).getUserRecordID().
            intValue();
      staffID = new Integer(selectedUserID);
      
      CalendarRetrievalManager crm = new CalendarRetrievalManager(
      		this.getSessionContainer(request),
      		this.getConnection(request));
      
      if (CalendarRecord.NAV_MODE_LIST_BY_DAY.equals(navMode)
      		|| CalendarRecord.NAV_MODE_LIST_BY_WEEK.equals(navMode)
      		|| CalendarRecord.NAV_MODE_LIST_BY_MONTH.equals(navMode)
      		|| CalendarRecord.NAV_MODE_LIST_SEARCH.equals(navMode)){

	      sortedList = crm.getSortedList(form,request,navMode,selectedUserID,staffID,startDate,endDate);
	      
	      Collections.sort(sortedList);
	      if (!Utility.isEmpty(sortedList)) {
	        eventList=intance.getEventList(sortedList);
	        newSortList = intance.getNewSortedList(sortedList);
	      }
      }
      
      if (CalendarRecord.NAV_MODE_LIST_EVENT.equals(navMode)
      		|| CalendarRecord.NAV_MODE_LIST_SEARCH.equals(navMode)){
      	newEventList = crm.getNewEventMeetingList(form,selectedUserID,selectedGroupID,startDate,endDate,navMode);
      }
      
      if (CalendarRecord.NAV_MODE_LIST_TODO.equals(navMode)
      		|| CalendarRecord.NAV_MODE_LIST_SEARCH.equals(navMode)){
      	newToDoList = crm.getNewToDoList(form,request,navMode);
      }  
	    
      request.setAttribute(this.getListName(), newSortList);
      request.setAttribute(this.toDoListName, newToDoList);
      request.setAttribute(this.userListName, userList);
      request.setAttribute("eventList", eventList);
      request.setAttribute("newEventList", newEventList);

    } catch (Exception e) {
      log.error(e, e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    }


    UserGroupDAObject userGroupDAO = new UserGroupDAObject(this.
        getSessionContainer(request), conn);
    request.setAttribute(this.groupListName, userGroupDAO.getPublicGroupList());
  }

  /**
   * search users
   * @param mapping                    mappiing for struts
   * @param form                       ActionForm for struts
   * @param request                    HttpServletRequest
   * @param response                   HttpServletResponse
   * @throws ApplicationException      Throws Exception if cannot get the list data from DAO object
   */
  public void getRecipeintListData(ActionMapping mapping,
                                   AbstractSearchForm form,
                                   HttpServletRequest request,
                                   HttpServletResponse response)
      throws ApplicationException {

    Connection conn = null;
    String navMode = null;
    HttpSession session = request.getSession();

    String appendedQuery = null;
    Timestamp startDate = null;
    Timestamp endDate = null;
    Calendar selectedDate = Calendar.getInstance();

    int selectedUserID = -1;
    Integer staffID = new Integer( -1);

  
    String[] userRecords = request.getParameterValues("userRecords");
    String[] userRoles = request.getParameterValues("userRoles");
    String[] userGroups = request.getParameterValues("userGroups");
    
    
    List selectedUserIDList = new ArrayList();
    List tmpList = new ArrayList();

     //getListNavMode
    navMode = intance.getListNavMode(request);
    try {
      conn = getConnection(request);

      //getSelectUserIDList
      selectedUserIDList = intance.getSelectUserIDList(this.getSessionContainer(
          request), this.getConnection(request), userRecords,
           userRoles, userGroups);

      //getselectedUserID
      //selectedUserID = intance.getSelectedUserID(this.getSessionContainer(
      //    request), request);

      //getRec StartDate and endDate and selectedDate
      ArrayList dateList = intance.getRecStartEndDate(request);
      selectedDate = (Calendar) dateList.get(0);
      startDate = (Timestamp) dateList.get(1);
      endDate = (Timestamp) dateList.get(2);
      logger.info("navMode='" + navMode + "'");

      CalendarUtility util = new CalendarUtility();
      staffID = util.getStaffRecordIDByUserID(this.getSessionContainer(request),
                                              conn);

      //get invite schedule
      Map selectedUserCalendarMap = new HashMap();
      selectedUserCalendarMap = intance.getSelectUserCalendarMap(this.
          getSessionContainer(request), this.getConnection(request),request, form,
          selectedUserIDList, startDate, endDate, appendedQuery);

      session.setAttribute("selectedUserCalendarMap", selectedUserCalendarMap);
      session.setAttribute("selectedUserIDList", selectedUserIDList);     
      session.setAttribute("userRecords", userRecords);
      session.setAttribute("userRoles", userRoles);
      session.setAttribute("userGroups", userGroups);
      request.setAttribute("selectedDate", selectedDate);

    } catch (Exception e) {
      log.error(e, e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    }

  }

  /**
   * function deleteListData is to delete data in list.
   * @param mapping                        mapping for struts
   * @param form                           ActionForm for struts
   * @param request                        HttpServletRequest
   * @param response                       HttpServletResponse
   * @throws ApplicationException          Throws Exception if cannot get the list data from DAO object
   */
  public void deleteListData(ActionMapping mapping, AbstractSearchForm form,
                             HttpServletRequest request,
                             HttpServletResponse response)
      throws ApplicationException {

    Connection conn = null;
    try {
      String[] arg = form.getBasicSelectedID();
      String[] itemToDel = null;

      if (arg != null) {
        conn = this.getConnection(request);
        SessionContainer sessionCtx = this.getSessionContainer(request);
        CalendarRecordDAObject calendarDAO = new CalendarRecordDAObject(this.
            getSessionContainer(request), this.getConnection(request));
        for (int i = 0; i < arg.length; i++) {
          itemToDel = TextUtility.splitString(arg[i], "|");
          if (itemToDel != null) {
            CalendarRecord calendarRecord = (CalendarRecord) calendarDAO.
                getObjectByID(new Integer(itemToDel[0]));
            if (CalendarRecord.EVENT_TYPE_CALENDAR_TODO.equals(itemToDel[1]) ||
                CalendarRecord.EVENT_TYPE_CALENDAR_EVENT.equals(itemToDel[1]) ||
                CalendarRecord.EVENT_TYPE_CALENDAR_MEETING.equals(itemToDel[1]))
              calendarDAO.SoftDelete(new Integer(itemToDel[0]));

            UpdateAlertDAObject updateAlertDAO = new UpdateAlertDAObject(
                                sessionCtx, conn);
                        UpdateAlertSystemLogDAObject updateAlertSystemLogDAO = new UpdateAlertSystemLogDAObject(
                                sessionCtx, conn);
                        UpdateAlertTypeDAObject updateAlertTypeDAO = new UpdateAlertTypeDAObject(
                                sessionCtx, conn);

                        UpdateAlert updateAlert = (UpdateAlert) updateAlertDAO
                                .getByObjectTypeObjectID(
                                        UpdateAlert.CALENDAR_TYPE, new Integer(
                                                itemToDel[0]));

                        if (!Utility.isEmpty(updateAlert)) {
                            List updateAlertTypeList = updateAlertTypeDAO
                                    .getByUpdateAlertIDByOwnerID(updateAlert
                                            .getID(), "ALL", sessionCtx
                                            .getUserRecordID());

                            for (int j = 0; j < updateAlertTypeList.size(); j++) {
                                UpdateAlertType updateAlertType = (UpdateAlertType) updateAlertTypeList
                                        .get(j);

                                //delete updateAlertSystemLog
                                UpdateAlertSystemLog updateAlertSystemLog = (UpdateAlertSystemLog) updateAlertSystemLogDAO
                                        .getByUpdateAlertTypeIDActionUserID(
                                                updateAlertType.getID(),
                                                sessionCtx.getUserRecordID());

                                if (!Utility.isEmpty(updateAlertSystemLog)) {
                                    updateAlertSystemLogDAO
                                            .deleteObject(updateAlertSystemLog);
                                }

                                //delete updateAlertType
                                updateAlertTypeDAO
                                        .deleteObject(updateAlertType);
                            }

                            //delete updateAlert
                            updateAlertDAO.deleteObject(updateAlert);
                        }

              //REMINDER HANDLING
              if (calendarRecord.getReminderType() != null &&
                  (calendarRecord.
                   getReminderType().indexOf(UpdateAlert.EMAIL_NOTIFICATION) >=
                   0)) {
                AlertManager am = new AlertManager(this.getSessionContainer(
                    request), conn);
                UpdateAlert delUpdateAlert = new UpdateAlert();
                delUpdateAlert.setObjectType(UpdateAlert.CALENDAR_TYPE);
                delUpdateAlert.setObjectID(calendarRecord.getID());
                delUpdateAlert.setCreatorName(calendarRecord.getCreatorName());
                List userRecordIDList = new ArrayList(1);
                userRecordIDList.add(this.getSessionContainer(request).
                                     getUserRecordID());
                java.util.Date date = new java.util.Date(calendarRecord.
                    getDatetime().getTime());

                try {
                  am.delScheduleJobNotification(delUpdateAlert);
                } catch (Exception e) {}
              }
            //}
            //Recurring
            if (calendarRecord.getIsRecurrence() != null) {
              CalendarRecurDAObject calendarRecurDAO = new
                  CalendarRecurDAObject(this.getSessionContainer(request), conn);
              calendarRecurDAO.deleteByCalendarID(calendarRecord.getID());
            }
          }
        }

        this.commit(request);
      }
      conn = null;
    } catch (ApplicationException appEx) {
      throw appEx;
    } catch (Exception e) {
      log.error(e, e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    }

}

}